/*
 * Copyright 2008 Mark Davidson.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

package org.doofer

import com.documentum.fc.client.*
import com.documentum.fc.common.*

/**
 * Provides convenience methods for getting object type information.
 *
 * @author Mark Davidson
 */
class TypeUtil {

    def qu = new QueryUtil()

    /**
     * Gets a list of child types for a given type name. The named
     * parameters are:
     *
     * <ul>
     * <li>session - the repository session</li>
     * <li>typeName - the type name</li>
     * </ul>
     *
     * @param params The named parameters. See description for more info.
     * @throws DfException
     */
    def getChildTypes(Map params) {
        def session = params.session
        def typeName = params.typeName
        def dql = "select r_type_name from dmi_type_info where any r_supertype in ('$typeName') order by r_type_name"
        def subTypes = qu.toList(session: session, dql: dql)
        subTypes*.r_type_name - params.typeName  // ensure that the current type is not in the returned list
    }

    /**
     * Checks whether an object type has a specific child type. The named
     * parameters are:
     *
     * <ul>
     * <li>session - the repository session</li>
     * <li>typeName - the type name</li>
     * <li>child - the child type to check for</li>
     * </ul>
     *
     * @param params The named parameters. See description for more info.
     * @throws DfException
     */
    def hasChildType(Map params) {
        def child = params.child
        getChildTypes(params).contains(child)
    }

    /**
     * Gets a list of parent types for a given type name. The named
     * parameters are:
     *
     * <ul>
     * <li>session - the repository session</li>
     * <li>typeName - the type name</li>
     * </ul>
     *
     * @param params The named parameters. See description for more info.
     * @throws DfException
     */
    def getParentTypes(Map params) {
        def session = params.session
        def parents = params.parents ?: []
        def typeName = params.typeName
        def recursive = params.recursive == null ? true : params.recursive

        def type = params.type
        if(!type) {
            type = session.getType(typeName)
        }

        def parentType = type.superType
        if(parentType) {
            parents << parentType.name

            if(recursive) {
                getParentTypes(session: session, parents: parents, type: parentType)
            }
        }

        parents
    }

    /**
     * Checks whether an object type has a specific parent type. The named
     * parameters are:
     *
     * <ul>
     * <li>session - the repository session</li>
     * <li>typeName - the type name</li>
     * <li>parent - the parent type to check for</li>
     * </ul>
     *
     * @param params The named parameters. See description for more info.
     * @throws DfException
     */
    def hasParentType(Map params) {
        def parent = params.parent
        getParentTypes(params).contains(parent)
    }
}